package main.java.common.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

/**
 * 根据IP地址获取详细地域信息
 * @author D
 *
 */
public class AddressUtils {
	/**
	 * @param content 
	 * 	请求的参数 格式： name=xxx&pwd=xxx
	 * @param encoding
	 * 	服务端请求的编码 
	 * @throws IOException 
	 */
	public static String getAddreess(String ip) throws IOException {
		String urlStr = "http://ip.taobao.com/service/getIpInfo.php";
		String returnStr = getResult(urlStr,ip);
		if(returnStr != null) {
			//处理返回的市区信息
			String[] temp = returnStr.split(",");
			if(temp.length < 3) {
				return "0" ; //无效ip
			}
			String region = (temp[5].split(":"))[1].replaceAll("\"","" );
			region  = decodeUnicode(region); //省份
			String country = "";
			String area = "";
			// String region = "";
			String city = "";
			String county = "";
			String isp = "";
			for (int i = 0; i < temp.length; i++) {
				switch (i) {
				case 1:
					country = (temp[i].split(":"))[2].replaceAll("\"", "");
					country = decodeUnicode(country);// 国家
					break;
				case 3:
					area = (temp[i].split(":"))[1].replaceAll("\"", "");
					area = decodeUnicode(area);// 地区
					break;
				case 5:
					region = (temp[i].split(":"))[1].replaceAll("\"", "");
					region = decodeUnicode(region);// 省份
					break;
				case 7:
					city = (temp[i].split(":"))[1].replaceAll("\"", "");
					city = decodeUnicode(city);// 市区
					break;
				case 9:
					county = (temp[i].split(":"))[1].replaceAll("\"", "");
					county = decodeUnicode(county);// 地区
					break;
				case 11:
					isp = (temp[i].split(":"))[1].replaceAll("\"", "");
					isp = decodeUnicode(isp); // ISP公司
					break;
				}
			}
			String address = region+city;
			if(StringUtils.isBlank(address)){
				address = "地球村";
			}
			return address;
		}
		return null;
	}
	
	/**
	 * 
	 * @param urlStr 请求的地址
	 * @param ip
	 * @return
	 * @throws IOException 
	 */
	private static String getResult(String urlStr, String ip) throws IOException {
		URL url = null;
		HttpURLConnection connection = null;
		DataOutputStream out = null;
		BufferedReader reader = null;
		
		try {
			url = new URL(urlStr);
			connection = (HttpURLConnection)url.openConnection();//新建链接实例
			/**
			 * 超时错误 由2s改为5s
			 */
			connection.setConnectTimeout(5000);//设置链接超时
			connection.setReadTimeout(5000);//设置读取数据超时
			connection.setDoOutput(true);//是否打开输出流
			connection.setRequestMethod("post"); //请求方式
			connection.setUseCaches(false);
			connection.connect();//打开链接端口
		    out = new DataOutputStream(connection.getOutputStream()); //打开输出流往服务端写数据
			out.writeBytes("ip=" + ip); //写数据，提交表单 name=xxx&pwd=xxx
			out.flush();
			out.close();
			reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));
			StringBuffer buffer = new StringBuffer();
			String line = "";
			while((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			reader.close();
			return buffer.toString();
		}catch(IOException e) {
			e.printStackTrace();
		}finally {
			if(connection != null) {
				connection.disconnect();
			}
			if(reader != null) {
				reader.close();
			}
			if(out != null) {
				out.close();
			}
		}
		return null;
	}
	
	/**
	 * unicode 转换成中文
	 * @param str
	 * @return
	 */
	public static String decodeUnicode(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);
		for (int x = 0; x < len;) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
						case '0':
						case '1':
						case '2':
						case '3':
						case '4':
						case '5':
						case '6':
						case '7':
						case '8':
						case '9':
							value = (value << 4) + aChar - '0';
							break;
						case 'a':
						case 'b':
						case 'c':
						case 'd':
						case 'e':
						case 'f':
							value = (value << 4) + 10 + aChar - 'a';
							break;
						case 'A':
						case 'B':
						case 'C':
						case 'D':
						case 'E':
						case 'F':
							value = (value << 4) + 10 + aChar - 'A';
							break;
						default:
							throw new IllegalArgumentException("Malformed      encoding.");
						}
					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't') {
						aChar = '\t';
					} else if (aChar == 'r') {
						aChar = '\r';
					} else if (aChar == 'n') {
						aChar = '\n';
					} else if (aChar == 'f') {
						aChar = '\f';
					}
					outBuffer.append(aChar);
				}
			} else {
				outBuffer.append(aChar);
			}
		}
		return outBuffer.toString();
	}
	
	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("X-Real-IP");
		if(!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)){
			return ip;
		}
		ip = request.getHeader("X-Forwarded-For");
		if(!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
			int index = ip.indexOf(",");
			if(index != -1) {
				return ip.substring(0, index);
			}else {
				return ip;
			}	
		}
		 if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
	            ip = request.getHeader("Proxy-Client-IP");
	        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
	            ip = request.getHeader("WL-Proxy-Client-IP");
	        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
	            ip = request.getHeader("HTTP_CLIENT_IP");
	        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
	            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
	        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
	            ip = request.getRemoteAddr();
		return ip;
	}
}
